package com.hmall.item;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hmall.item.domain.dto.ItemESDTO;
import com.hmall.item.domain.po.Item;
import com.hmall.item.service.IItemService;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.List;

@SpringBootTest
class ES01Test {

    private RestHighLevelClient client;

    @BeforeEach
    void before() {
        client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.101.200:9200")
        ));
    }

    @AfterEach
    void after() throws IOException {
        client.close();
    }
    static final String MAPPINGS = "{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"id\": {\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"name\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\"\n" +
            "      },\n" +
            "      \"price\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"stock\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"image\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"category\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"brand\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"sold\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"commentCount\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"isAD\":{\n" +
            "        \"type\": \"boolean\"\n" +
            "      },\n" +
            "      \"updateTime\":{\n" +
            "        \"type\": \"date\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";

//*******************【 1.索引操作】***************************************************
    // 1.1. 创建索引  PUT /index
    @Test
    void testCreateIndex() throws IOException {
        //1.创建索引对象
        CreateIndexRequest request = new CreateIndexRequest("items");
        //2.加载参数mapping
        request.source(MAPPINGS,  XContentType.JSON);
        //3.发送请求
        client.indices().create(request, RequestOptions.DEFAULT);

    }

    // 1.2. 删除索引  DELETE /index
    @Test
    void testDeleteIndex() throws IOException {
        //1．删除索引请求对象
        DeleteIndexRequest request = new DeleteIndexRequest("items");
        //2.发送请求
        client.indices().delete(request, RequestOptions.DEFAULT);
    }

    // 1.3 判断索引是否存在
    @Test
    void testExistsIndex() throws IOException {
        //1．得到查询索引的请求对象
        GetIndexRequest request = new GetIndexRequest("items");
        //2.发送请求
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

//*******************【 2.文档操作】***************************************************

    // 2.1 添加文档 （从MYSQL查询，添加到ES）
    @Autowired
    private IItemService itemService;
    @Test
    void testAddDocument() throws IOException {
        //1.询数据库，得到商品对象：以id=317578为例
        Item item = itemService.getById(317578L);
        //2.将item对象转为ItemESDto对象
        ItemESDTO esdto = BeanUtil.copyProperties(item, ItemESDTO.class);
        //3.转为json
        String jsonStr = JSONUtil.toJsonStr(esdto);
        //4．创建请求对象
        IndexRequest request = new IndexRequest("items").id(esdto.getId());
        //5．加载json参数
        request.source(jsonStr, XContentType.JSON);
        //6．发送请求
        client.index(request, RequestOptions.DEFAULT);


    }

    // 2.2 根据id 查询文档: GET /index/_doc/{id}
    @Test
    void testGetDocumentById() throws IOException {
        //1．创建请求对象
        GetRequest request = new GetRequest("items", "317578");
        //2．发送请求
        GetResponse response= client.get(request, RequestOptions.DEFAULT);
        //3.解析数据
        String str = response.getSourceAsString();
        System.out.println(str);
    }

    // 2.3 根据id删除文档：  DELETE /index/_doc/{id}
    @Test
    void testDeleteDocumentById() throws IOException {
        //1.建请求对象
        DeleteRequest items = new DeleteRequest("items", "317578");
        //2.发送请求
        client.delete(items, RequestOptions.DEFAULT);

    }

    // 2.4 根据id修改文档
    @Test
    void testUpdateById() throws IOException {

    }

//*******************【 3. 批量导入 】***************************************************
    // 3. 批量导入： bulk
    @Test
    void testBulkRequest() throws IOException {
        //分页参数
        int  page = 1;
        int size = 1000;
        //批量请求的buLk
        BulkRequest bulkRequest = new BulkRequest();
        //一直查询，知道没有数据为止
        while (true){
            System.out.println("正在导入数据第..."+page+"页数据");
            //1．做分页查询
            Page<Item> itemPage = itemService.page(new Page<>(page, size));
            List<Item> list = itemPage.getRecords();
            //设置终止条件
            if(list.size()==0){
                break;
            }
            //2．批量导入
            List<ItemESDTO> itemESDTOS = BeanUtil.copyToList(list, ItemESDTO.class);
            itemESDTOS.forEach(
                    itemESDTO -> {
                        String jsonStr = JSONUtil.toJsonStr(itemESDTO);
                        IndexRequest request = new IndexRequest("items").id(itemESDTO.getId());
                        request.source(jsonStr, XContentType.JSON);
                        //添加单个请求到buLkRequest
                        bulkRequest.add(request);
                    }
            );
            //3.发送请求
            client.bulk(bulkRequest, RequestOptions.DEFAULT);
            page++;
        }


    }

}